﻿/*
 *  Icon Pro
 *  Copyright (C) 2015 Herbert Lausmann. All rights reserved.
 *  http://herbertdotlausmann.wordpress.com/
 *  herbert.lausmann@hotmail.com
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *   1. Redistributions of source code must retain the above copyright
 *      notice, this list of conditions and the following disclaimer.
 *   2. Redistributions in binary form must reproduce the above copyright
 *      notice and this list of conditions.    
 */
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using HL.IconPro.Lib.Core.DIB;
using HL.IconPro.Lib.Core;

namespace HL.IconPro.Lib.Wpf
{
    public class IconBitmapEncoder : IconBitmapBase
    {
        #region Constructors

        #endregion

        #region Destructors

        #endregion

        #region Fields
        private bool _UsePngCompression = true;
        #endregion

        #region Properties
        public bool UsePngCompression
        {
            get { return _UsePngCompression; }
            set { _UsePngCompression = value; }
        }
        #endregion

        #region Procedures
        public void Save(System.IO.Stream Output)
        {
            IconFile IconFile = new IconFile();
            foreach (BitmapFrame frame in _Frames)
            {
                IconFrame iconFrame = IconFrame.Create(GetBitmapFrameBuffer(frame));
                IconFile.IconFrames.Add(iconFrame);
            }
            IconFile.Write(Output);
        }
        private byte[] GetBitmapFrameBuffer(BitmapFrame Source)
        {
            if (UsePngCompression && Source.PixelWidth == 256)
            {
                PngBitmapEncoder pngEncoder = new PngBitmapEncoder();
                pngEncoder.Frames.Add(Source);
                System.IO.MemoryStream frameBuffer = new System.IO.MemoryStream();
                pngEncoder.Save(frameBuffer);
                pngEncoder = null;
                return frameBuffer.GetBuffer();
            }
            else
            {
                BmpBitmapEncoder bmpEncoder = new BmpBitmapEncoder();
                bmpEncoder.Frames.Add(Source);
                System.IO.MemoryStream frameBuffer = new System.IO.MemoryStream();
                bmpEncoder.Save(frameBuffer);
                bmpEncoder = null;
                DIBitmap dib = DIBitmap.FromBitmapFile(frameBuffer);
                dib.icAND = CreateAndMask(Source);
                dib.icHeader.biHeight *= 2;
                return dib.GetBytes();
            }
        }
        private byte[] CreateAndMask(BitmapSource bp)
        {
            FormatConvertedBitmap output = new FormatConvertedBitmap(bp, PixelFormats.Indexed1, null, 20);
            WriteableBitmap w = new WriteableBitmap(output);
            byte[] buffer = new byte[w.BackBufferStride * w.PixelHeight];
            System.Runtime.InteropServices.Marshal.Copy(w.BackBuffer, buffer, 0, w.BackBufferStride * w.PixelHeight);
            return DIBitmap.FlipYBuffer(buffer, w.PixelWidth, w.PixelHeight, w.BackBufferStride);
        }
        #endregion

        #region Static

        #endregion

        #region Others

        #endregion
    }
}
